/*
 * EffectsCalculator.h
 *
 *  Created on: 27.01.2021
 *      Author: Yannick / Jon Lidgard / Vincent Manoukian
 */

#ifndef EFFECTSCALCULATOR_H_
#define EFFECTSCALCULATOR_H_

//#include "ClassChooser.h"
#include "ffb_defs.h"
#include "Filters.h"
//#include "hid_cmd_defs.h"

#define EFFECT_THREAD_MEM 			128
#define EFFECT_THREAD_PRIO 			20 // low priority for stat

#define INTERNAL_SCALER_SPRING		180			//
#define INTERNAL_SCALER_DAMPER 		80
#define INTERNAL_SCALER_FRICTION 	45
#define INTERNAL_SCALER_INERTIA 	4

#define CUSTOM_PROFILE_ID 			1

#define EC_STATES_SIZE				12

struct Axis;
struct metric_t;

// default effect gains
typedef struct effect_gain_t {
	uint8_t friction;// = 254;
	uint8_t spring;// = 64;
	uint8_t damper;// = 64;
	uint8_t inertia;// = 127;
	uint8_t periodic;
}effect_gain_t;

typedef struct effect_scaler_t {
	float friction;// = 1.0; //0.4 * 40;
	float spring ;//= 16.0;
	float damper;// = 4.0; //2 * 40 * 2
	float inertia;// = 2.0;//0.5 * 40;
	float periodic;
}effect_scaler_t;

typedef struct effect_biquad_t {
	struct biquad_constant_t constant	;	//= { 500, 70 };
	struct biquad_constant_t friction	;	//= { 50, 20 };
	struct biquad_constant_t damper 	;	//= { 30, 40 };
	struct biquad_constant_t inertia	;	//= { 15, 20 };
}effect_biquad_t;

typedef struct effect_stat_t {
	int16_t current	;
	int16_t max		;
	uint16_t nb		;
}effect_stat_t;

//enum EffectsCalculator_commands{
//	ffbfiltercf,ffbfiltercf_q,effects,spring,friction,damper,inertia,
//	damper_f, damper_q, friction_f, friction_q, inertia_f, inertia_q, calcfilterProfileId,
//	frictionPctSpeedToRampup,
//	monitorEffect, effectsDetails, effectsForces,
//};

typedef struct EffectsCalculator
{

	FFB_Effect* pEffects;				// ptr to effects array in HidFFB
	
	uint8_t directionEnableMask;	
	// Filters	
	effect_biquad_t filter[2];			// is the default profile and the custom for CFFilter, CUSTOM_PROFILE_ID is the custom slot
	uint8_t filterProfileId;	
	const uint32_t calcfrequency;		// HID frequency 1khz
	const float qfloatScaler;

	// Rescale factor for conditional effect to boost or decrease the intensity
	uint8_t global_gain;
	effect_gain_t gain;
	effect_scaler_t scaler;
	uint8_t frictionPctSpeedToRampup;	// define the max value of the range (0..5% of maxspeed) where torque is rampup on friction

	// FFB status
	bool effects_active;				// was ffb_active
	uint32_t effects_used;
	effect_stat_t effects_stats[EC_STATES_SIZE]; // [0..12 effect types]
	bool isMonitorEffect;

}EffectsCalculator;

void EC_Init(EffectsCalculator* ec);
void EC_setDirectionEnableMask(EffectsCalculator* ec,uint8_t mask);
void EC_calculateEffects(EffectsCalculator* ec,struct Axis* axes,uint8_t axisCount);
bool EC_isActive(EffectsCalculator* ec);
void EC_setActive(EffectsCalculator* ec,bool active);
void EC_setGain(EffectsCalculator* ec,uint8_t gain);
void EC_setFilters(EffectsCalculator* ec,FFB_Effect *effect);
void EC_logEffectType(EffectsCalculator* ec,uint8_t type,bool remove);
void EC_setEffectsArray(EffectsCalculator* ec,FFB_Effect *pEffects);
void EC_logEffectState(EffectsCalculator* ec,uint8_t type,uint8_t state);
void EC_restoreFlash(EffectsCalculator* ec);
void EC_Filter_Write(EffectsCalculator* ec,uint8_t ecNum,uint16_t filterValue);
void EC_Filter_Read(EffectsCalculator* ec,uint8_t ecNum,uint16_t* pfilterValue);
void EC_Gain_Scaler_Write(EffectsCalculator* ec,uint8_t ecNum,uint16_t gains);
void EC_Gain_Scaler_Read(EffectsCalculator* ec,uint8_t ecNum,uint16_t* pgains);

#endif /* EFFECTSCALCULATOR_H_ */


